package zouran.exception;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.TypeMismatchException;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindingResult;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingPathVariableException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.NoHandlerFoundException;
import zouran.result.ResultMap;

import javax.validation.ConstraintViolationException;
import java.util.Arrays;

/**
 * Author：zouran
 * Date：2023/4/2  0:41
 * Description:
 */
@Slf4j
@RestControllerAdvice
public class ControllerException {
    private final ResultMap resultMap;

    public ControllerException(ResultMap resultMap) {
        this.resultMap = resultMap;
    }

    /**
     * description: params range exception
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResultMap MethodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {
        BindingResult bindingResult = e.getBindingResult();
        if (bindingResult.hasErrors())
            return resultMap.errorRequest(bindingResult.getAllErrors().get(0).getDefaultMessage());
        else return resultMap.errorRequest();
    }

    /**
     * description: target url not exist
     */
    @ExceptionHandler(value = NoHandlerFoundException.class)
    public ResultMap NoHandlerFoundExceptionHandler(NoHandlerFoundException e) {
        log.info("NoHandlerFoundException");
        System.out.println(Arrays.toString(e.getStackTrace()).split(",")[0]);
        return resultMap.errorPath();
    }

    /**
     * description:request method exception
     */
    @ExceptionHandler(value = HttpRequestMethodNotSupportedException.class)
    public ResultMap HttpRequestMethodNotSupportedExceptionHandler(HttpRequestMethodNotSupportedException e) {
        log.info("HttpRequestMethodNotSupportedException");
        System.out.println(Arrays.toString(e.getStackTrace()).split(",")[0]);
        return resultMap.error(403, "request method error!");
    }

    /**
     * description:request header type exception
     */
    @ExceptionHandler(value = HttpMediaTypeNotSupportedException.class)
    public ResultMap HttpMediaTypeNotSupportedExceptionHandler(HttpMediaTypeNotSupportedException e) {
        log.info("HttpMediaTypeNotSupportedException");
        System.out.println(Arrays.toString(e.getStackTrace()).split(",")[0]);
        return resultMap.error(406, "invalid request method");
    }

    /**
     * description:/licence/{licenceId} licenceId not exist in url
     */
    @ExceptionHandler(value = MissingPathVariableException.class)
    public ResultMap MissingPathVariableException(MissingPathVariableException e) {
        log.info("MissingPathVariableException");
        System.out.println(Arrays.toString(e.getStackTrace()).split(",")[0]);
        return resultMap.error(403, "invalid request path params");
    }

    /**
     * description:miss request params exception
     */
    @ExceptionHandler(value = MissingServletRequestParameterException.class)
    public ResultMap MissingServletRequestParameterExceptionHandler(MissingServletRequestParameterException e) {
        log.info("MissingServletRequestParameterException");
        System.out.println(Arrays.toString(e.getStackTrace()).split(",")[0]);
        return resultMap.errorRequest();
    }

    /**
     * description:request params type exception
     */
    @ExceptionHandler(value = TypeMismatchException.class)
    public ResultMap TypeMismatchExceptionHandler(TypeMismatchException e) {
        log.info("TypeMismatchException");
        System.out.println(Arrays.toString(e.getStackTrace()).split(",")[0]);
        return resultMap.errorRequest();
    }

    /**
     * description:request params name exception
     */
    @ExceptionHandler(value = IllegalStateException.class)
    public ResultMap IllegalStateExceptionHandler(IllegalStateException e) {
        log.info("IllegalStateException");
        System.out.println(Arrays.toString(e.getStackTrace()).split(",")[0]);
        return resultMap.errorRequest();
    }

    /**
     * description:response header type exception 请求格式问题
     */
    @ExceptionHandler(value = HttpMessageNotReadableException.class)
    public ResultMap HttpMessageNotReadableExceptionHandler(HttpMessageNotReadableException e) {
        log.info("HttpMessageNotReadableException");
        System.out.println(Arrays.toString(e.getStackTrace()).split(",")[0]);
        return resultMap.error("invalid request Content-Type");
    }

    /**
     * description:response header type exception 请求格式问题
     */
    @ExceptionHandler(value = ConstraintViolationException.class)
    public ResultMap ConstraintViolationExceptionHandler(ConstraintViolationException e) {
        log.info("ConstraintViolationException");
        System.out.println(Arrays.toString(e.getStackTrace()).split(",")[0]);
        return resultMap.errorRequest(e.getMessage());
    }

}
